﻿using System.Linq.Expressions;
using Testudo.Core.ViewModels;

namespace Testudo.Core;

public interface IRepository<TEntity>
    where TEntity : IEntity
{
    #region Any

    Task<bool> AnyAsync(Expression<Func<TEntity, bool>> filter = null);

    #endregion

    #region List

    Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> filter = null);

    #endregion

    #region PagingList

    Task<PagingList<TEntity>> PagingListAsync(Expression<Func<TEntity, bool>> filter = null, int pageIndex = 1,
        int pageSize = 10);

    #endregion

    #region Create

    TEntity Create(TEntity target);
    Task<TEntity> CreateAsync(TEntity target);

    #endregion

    #region Update

    TEntity Update(TEntity target);
    Task<TEntity> UpdateAsync(TEntity target);
    Task<TEntity> UpdateAsync(Guid id, IDictionary<string, object> data);

    #endregion

    #region Patch

    Task<TEntity> PatchAsync(PatchData patch);
    Task<TEntity> SlashAsync(SlashData slash);

    #endregion

    #region Delate

    bool Delete(Guid id);
    Task<bool> DeleteAsync(Guid id);
    Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> filter);

    #endregion

    #region Count

    long Count(Expression<Func<TEntity, bool>> filter = null);
    Task<long> CountAsync(Expression<Func<TEntity, bool>> filter = null);

    #endregion

    #region FirstOrDefault

    TEntity FirstOrDefault(Expression<Func<TEntity, bool>> filter = null);
    Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> filter = null);

    #endregion

    #region Get

    TEntity Get(Guid id);
    Task<TEntity> GetAsync(Guid id);

    #endregion
}

public interface IRepository<TEntity, TVM, in TCreateVM, in TUpdateVM>
    where TEntity : IEntity
    where TCreateVM : CreateVM
    where TVM : class, IVMBase
{
    Task<TVM> CreateAsync(TCreateVM vm);

    Task<TVM> UpdateAsync(TUpdateVM vm);
    Task<TVM> PatchAsync(PatchData patch);
    Task<TVM> SlashAsync(SlashData slash);
    Task<TVM> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> filter = null);

    #region Create

    Task<TVM> CreateAsync(TEntity target);

    #endregion

    #region List

    Task<List<TVM>> GetListAsync(Expression<Func<TEntity, bool>> filter = null);

    #endregion

    #region PagingList

    Task<PagingList<TVM>> PagingListAsync(Expression<Func<TEntity, bool>> filter = null, int pageIndex = 1,
        int pageSize = 10);

    #endregion

    #region Update

    Task<TVM> UpdateAsync(TEntity target);
    Task<TVM> UpdateAsync(Guid id, IDictionary<string, object> data);

    #endregion

    #region Get

    TVM Get(Guid id);
    Task<TVM> GetAsync(Guid id);

    #endregion

    #region Delate

    bool Delete(Guid id);
    Task<bool> DeleteAsync(Guid id);
    Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> filter);

    #endregion
}